package edu.hawaii.duedates;

import java.util.Calendar;

/**
 * Book class used to store information on books borrowed.
 * 
 * @author John Zhou
 * @author John Ly
 */
public class BorrowedItem implements Comparable<BorrowedItem> {
  private final String title;
  private final Calendar duedate;
  private final String type;
  private final String lender;

  /**
   * Constructor for BorrowedItem class.
   * 
   * @param title The title of the BorrowedItem.
   * @param duedate The due date of the BorrowedItem.
   * @param type The type of the BorrowedItem.
   * @param lender The lender of the BorrowedItem.
   */
  public BorrowedItem(String title, Calendar duedate, String type, String lender) {
    this.title = title;
    this.duedate = duedate;
    this.type = type;
    this.lender = lender;
  }

  /**
   * Prints out the BorrowedItem in a table-row form. For example,
   * "Jan 15, 2009 | Cat in the Hat | Book | Lender".
   * 
   * @return A String containing the book info.
   */
  public String toString() {
    int charsPerRow = 50;
    // "Due Date | Title | Lender | Book "
    String format = "%1$-14.14s | %2$-50.50s | %3$-10.10s | %4$-20.20s\n";
    int month = this.duedate.get(Calendar.MONTH) + 1;
    String date = "" + month;
    date = date + "-" + this.duedate.get(Calendar.DAY_OF_MONTH);
    date = date + "-" + this.duedate.get(Calendar.YEAR);
    if (this.title.length() <= charsPerRow) {
      return String.format(format, date, this.title, this.type, this.lender);
    }

    String output = String.format(format, date, this.title, this.type, this.lender);
    int rowsForTitle = this.title.length() / charsPerRow;
    if (this.title.length() % charsPerRow != 0) {
      rowsForTitle++;
    }
    for (int i = 1; i < rowsForTitle; i++) {
      String titleLong = this.title.substring(charsPerRow * i);
      output = output.concat(String.format(format, "", titleLong, "", ""));
    }
    return output;
  }

  /**
   * Returns title of the book.
   * 
   * @return title The title of the book.
   */
  public String getTitle() {
    return this.title;
  }

  /**
   * Return the due date in a printable String form. This is mainly for debugging purposes.
   * 
   * @return The String in (mm-dd-yyyy hour:min:sec:msec).
   */
  public String printDueDate() {
    String output = "";
    output = output.concat("" + (this.duedate.get(Calendar.MONTH) + 1));
    output = output.concat("-" + this.duedate.get(Calendar.DATE));
    output = output.concat("-" + this.duedate.get(Calendar.YEAR));
    output = output.concat(" " + this.duedate.get(Calendar.HOUR_OF_DAY));
    output = output.concat(":" + this.duedate.get(Calendar.MINUTE));
    output = output.concat(":" + this.duedate.get(Calendar.SECOND));
    output = output.concat(":" + this.duedate.get(Calendar.MILLISECOND));
    return output;
  }

  /**
   * Returns due date of the BorrowedItem.
   * 
   * @return The due date of the BorrowedItem.
   */
  public Calendar getDueDate() {
    return this.duedate;
  }

  /**
   * Returns the lender of the BorrowedItem.
   * 
   * @return The lender of the BorrowedItem
   */
  public String getLender() {
    return this.lender;
  }

  /**
   * Returns the type of the BorrowedItem.
   * 
   * @return The type of the BorrowedItem.
   */
  public String getType() {
    return this.type;
  }

  /**
   * Compare due dates so that BorrowedItem can be sorted by due date.
   * 
   * @param duedate2 The due date that will be compared.
   * @return A negative, zero, or a positive integer corresponding to less than, equal to, or
   * greater than.
   */
  public int compareTo(BorrowedItem duedate2) {
    return this.duedate.compareTo(duedate2.duedate);
  }

  /**
   * Override equals in order to compare BorrowedItem objects.
   * 
   * @param obj The BorrowedItem that will be compared.
   * @return If BorrowedItem object is null or wrong type returns false. Else if the due dates of
   * the objects to be compared are the same, then returns true.
   */
  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof BorrowedItem)) {
      return false;
    }
    BorrowedItem c = (BorrowedItem) obj;
    return c.duedate.equals(this.duedate);
  }

  /**
   * Override hashCode in order to pass findBugs. HashCode isn't used in this program.
   * 
   * @return Arbitrary constant since hashCode isn't used.
   */
  @Override
  public int hashCode() {
    assert false : "hashCode not designed";
    return 1; // any arbitrary constant will do
  }
}
